package MainControl;

import Instrument.TestingMachine;
import Model.Pulsator;
import Model.Roller;
import Tool.GlobalVariable;
import Tool.HexString;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;

public class CollectionThread implements Runnable {
    private boolean run = true;
    public int testUnitNo;
    private Instant restartTime;
    public String modelAndType = "";
    public Socket collectionSocket;
    public OutputStream collectionOutStream;
    public InputStream collectionInStream;
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void TerminateThread() {
        this.run = false;
    }

    public void RestartThread() {
        this.run = true;
    }

    public CollectionThread(int testUnitNoin, String modelAndTypein, Socket collectionSocketin,
                            OutputStream collectionOutStreamin, InputStream collectionInStreamin) {
        this.testUnitNo = testUnitNoin;
        this.modelAndType = modelAndTypein;
        this.collectionSocket = collectionSocketin;
        this.collectionInStream = collectionInStreamin;
        this.collectionOutStream = collectionOutStreamin;
    }

    public void SendCollectionCommand() {
        byte collectionDataCommand[] = new byte[13];
        collectionDataCommand[0] = (byte) 0xFF;
        collectionDataCommand[1] = (byte) 0xFF;
        collectionDataCommand[2] = (byte) 0x0A;
        collectionDataCommand[3] = (byte) 0x00;
        collectionDataCommand[4] = (byte) 0x00;
        collectionDataCommand[5] = (byte) 0x00;
        collectionDataCommand[6] = (byte) 0x00;
        collectionDataCommand[7] = (byte) 0x00;
        collectionDataCommand[8] = (byte) 0x00;
        collectionDataCommand[9] = (byte) 0x01;
        collectionDataCommand[10] = (byte) 0x4D;
        collectionDataCommand[11] = (byte) 0x01;
        collectionDataCommand[12] = (byte) 0x59;
        try {
            GlobalVariable.commandWriters.get(testUnitNo).write(collectionDataCommand);
            Thread.sleep(100);
            GlobalVariable.commandWriters.get(testUnitNo).write(collectionDataCommand);
            Thread.sleep(200);
            GlobalVariable.commandWriters.get(testUnitNo).write(collectionDataCommand);
            System.out.println("重新发送采集命令");
        } catch (Exception e) {
            System.out.println("未能成功发送采集命令");
        }
    }

    public void RestartMachine() {
        byte powerOff[] = new byte[15];
        powerOff[0] = (byte) 0xFF;
        powerOff[1] = (byte) 0xFF;
        powerOff[2] = (byte) 0x0C;
        powerOff[3] = (byte) 0x00;
        powerOff[4] = (byte) 0x00;
        powerOff[5] = (byte) 0x00;
        powerOff[6] = (byte) 0x00;
        powerOff[7] = (byte) 0x00;
        powerOff[8] = (byte) 0x00;
        powerOff[9] = (byte) 0x01;
        powerOff[10] = (byte) 0x5D;
        powerOff[11] = (byte) 0x01;
        powerOff[12] = (byte) 0x00;
        powerOff[13] = (byte) 0x00;
        powerOff[14] = (byte) 0x6B;
        //开机
        byte powerOn[] = new byte[15];
        powerOn[0] = (byte) 0xFF;
        powerOn[1] = (byte) 0xFF;
        powerOn[2] = (byte) 0x0C;
        powerOn[3] = (byte) 0x00;
        powerOn[4] = (byte) 0x00;
        powerOn[5] = (byte) 0x00;
        powerOn[6] = (byte) 0x00;
        powerOn[7] = (byte) 0x00;
        powerOn[8] = (byte) 0x00;
        powerOn[9] = (byte) 0x01;
        powerOn[10] = (byte) 0x5D;
        powerOn[11] = (byte) 0x01;
        powerOn[12] = (byte) 0x00;
        powerOn[13] = (byte) 0x01;
        powerOn[14] = (byte) 0x6C;
        //启动
        byte powerStart[] = new byte[15];
        powerStart[0] = (byte) 0xFF;
        powerStart[1] = (byte) 0xFF;
        powerStart[2] = (byte) 0x0C;
        powerStart[3] = (byte) 0x00;
        powerStart[4] = (byte) 0x00;
        powerStart[5] = (byte) 0x00;
        powerStart[6] = (byte) 0x00;
        powerStart[7] = (byte) 0x00;
        powerStart[8] = (byte) 0x00;
        powerStart[9] = (byte) 0x01;
        powerStart[10] = (byte) 0x5D;
        powerStart[11] = (byte) 0x21;
        powerStart[12] = (byte) 0x00;
        powerStart[13] = (byte) 0x01;
        powerStart[14] = (byte) 0x8C;
        for (int i = 0; i < 5; i++) {
            try {
                GlobalVariable.commandWriters.get(testUnitNo).write(powerOff);
                GlobalVariable.commandWriters.get(testUnitNo).flush();
                Thread.sleep(200);
            } catch (Exception e) {
            }
        }
        for (int i = 0; i < 5; i++) {
            try {
                GlobalVariable.commandWriters.get(testUnitNo).write(powerOn);
                GlobalVariable.commandWriters.get(testUnitNo).flush();
                Thread.sleep(200);
            } catch (Exception e) {
            }
        }
        for (int i = 0; i < 5; i++) {
            try {
                GlobalVariable.commandWriters.get(testUnitNo).write(powerStart);
                GlobalVariable.commandWriters.get(testUnitNo).flush();
                Thread.sleep(200);
            } catch (Exception e) {
            }
        }
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        Integer currentTestUnitID = testUnitNo;// 当前正在测试的台位号
        String currentModelAndType = modelAndType;// 当前测试的台位所对应的洗衣机类型
        TestingMachine tempMachine = GlobalVariable.machines.get(currentTestUnitID);
        byte ackBack[] = new byte[11];
        ackBack[0] = (byte) 0xFF;
        ackBack[1] = (byte) 0xFF;
        ackBack[2] = (byte) 0x08;
        ackBack[3] = (byte) 0x00;
        ackBack[4] = (byte) 0x00;
        ackBack[5] = (byte) 0x00;
        ackBack[6] = (byte) 0x00;
        ackBack[7] = (byte) 0x00;
        ackBack[8] = (byte) 0x00;
        ackBack[9] = (byte) 0x05;
        ackBack[10] = (byte) 0x0D;
        byte stopAlarm[] = new byte[11];
        stopAlarm[0] = (byte) 0xFF;
        stopAlarm[1] = (byte) 0xFF;
        stopAlarm[2] = (byte) 0x08;
        stopAlarm[3] = (byte) 0x00;
        stopAlarm[4] = (byte) 0x00;
        stopAlarm[5] = (byte) 0x00;
        stopAlarm[6] = (byte) 0x00;
        stopAlarm[7] = (byte) 0x00;
        stopAlarm[8] = (byte) 0x00;
        stopAlarm[9] = (byte) 0x09;
        stopAlarm[10] = (byte) 0x11;
        Roller rollerDataAnalizer = null;
        Pulsator pulsatorDataAnalizer = null;
        if (currentModelAndType.trim().equals("1")) {
            pulsatorDataAnalizer = new Pulsator();
        }
        if (currentModelAndType.trim().equals("2")) {
            rollerDataAnalizer = new Roller();
        }
        while (run) {
            this.collectionSocket = GlobalVariable.connections.get(testUnitNo);
            this.collectionInStream = GlobalVariable.dataReaders.get(testUnitNo);
            this.collectionOutStream = GlobalVariable.commandWriters.get(testUnitNo);
            byte command[] = new byte[15];
            command[0] = (byte) 0xFF;
            command[1] = (byte) 0xFF;
            command[2] = (byte) 0x0C;
            command[3] = (byte) 0x00;
            command[4] = (byte) 0x00;
            command[5] = (byte) 0x00;
            command[6] = (byte) 0x00;
            command[7] = (byte) 0x00;
            command[8] = (byte) 0x00;
            command[9] = (byte) 0xF1;
            command[10] = (byte) 0x00;
            command[11] = (byte) 0x00;
            command[12] = (byte) 0x00;
            command[13] = (byte) 0x50;
            command[14] = (byte) 0x4D;
            try {
                GlobalVariable.commandWriters.get(testUnitNo).write(command);
            } catch (Exception e) {
                MainControl.reInit(testUnitNo);
            }
            this.modelAndType = GlobalVariable.testingUnitsID.get(testUnitNo);
            if (this.collectionOutStream != null && this.collectionInStream != null && collectionSocket != null) {
                String collectedValue = "";
                String result6D = "";
                String result7D = "";
                String date7DTemp = "";
                String alarm = "";
                int readCount = 0;
                byte[] readBuffer = new byte[2048];
                try {
                    readCount = collectionInStream.available();
                    if (readCount > 0) {
                        readCount = collectionInStream.read(readBuffer);
                        if (readBuffer[10] == 0x7D && readBuffer[11] == 0x01 && readCount > readBuffer[2])
                            collectionOutStream.write(ackBack);
                        if (readBuffer[10] == 0x0F && readBuffer[11] == 0x5A && readCount > readBuffer[2])
                            collectionOutStream.write(stopAlarm);
                    } else {
                        Thread.sleep(500);
                        continue;
                    }
                } catch (SocketTimeoutException e) {
                    System.out.println("--------------------SocketTimeoutException------------------");
                    e.printStackTrace();
                    // 捕获到超时信息，马上继续执行
                    continue;
                } catch (SocketException e) {
                    System.out.println("--------------------SocketException------------------");
                    e.printStackTrace();
                    // 捕获到连接异常，重新进行初始化
                    MainControl.reInit(currentTestUnitID);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    continue;
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println(format.format(new Date()) + "第" + currentTestUnitID + "个设备采集异常！");
                    System.out.println("--------------------尝试新建Socket连接----------------");
                    // 一旦发生采集异常本台位的采集信息会停止，需要重新开测
                    try {
                        collectionSocket.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    MainControl.reInit(currentTestUnitID);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    continue;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (readCount > 0) {
                    collectedValue = HexString.parseString(readBuffer, readCount).trim();
                    collectedValue = collectedValue.replaceAll(" +", " ");
                    // 去掉FF 55
                    String responses[] = collectedValue.split("FF FF");
                    // 去掉空格,同时将FF 55替换成FF
                    for (int j = 1; j < responses.length; j++) {
                        responses[j] = responses[j].trim();
                        responses[j] = responses[j].replaceAll("FF 55", "FF");
                    }
                    for (int responseCount = 1; responseCount < responses.length; responseCount++) {
                        System.out.println(format.format(new Date()) + "台位" + currentTestUnitID + ">>>>>>>>>>>输出第"
                                + responseCount + "条采集数据:>>>>>>>>>>>>>>" + responses[responseCount]);
                        // 判断是否是C1 D12G3LU1型号 发命令FF FF 0C 00 00 00 00 00 00 F1 00 00
                        // 00
                        // 50 4D
                        // 滚筒
                        // wifi确认信号

                        // 接收到命令停止发送命令的指令
                        try {
                            if (responses[responseCount].trim().length() > 40) {
                                String responseType = responses[responseCount].substring(24, 29);
                                // 波轮
                                if (currentModelAndType.equals("1")) {
                                    if (responseType.equals("7D 01")) {
                                        String pulsator7D[] = responses[responseCount].trim().split(" ");
                                        if (pulsator7D.length == 83) {
                                            result7D = pulsatorDataAnalizer.get7DData("FF FF " + responses[responseCount].trim());
                                            result7D = "!DATA#" + "UNITID:" + currentTestUnitID + "#" + result7D;
                                            //发送开机指令的逻辑，只有两侧间隔1min以上时才发送
                                            if (pulsatorDataAnalizer.ifNeedRestart == true) {
                                                if (restartTime != null) {
                                                    if (Duration.between(restartTime, Instant.now()).getSeconds() > 60) {
                                                        RestartMachine();
                                                        pulsatorDataAnalizer.ifNeedRestart = false;
                                                        restartTime = Instant.now();
                                                    } else
                                                        continue;
                                                } else {
                                                    restartTime = Instant.now();
                                                    RestartMachine();
                                                    pulsatorDataAnalizer.ifNeedRestart = false;
                                                }
                                            }
                                        } else {
                                            System.out.println("------------接收的波轮洗衣机数据不完整----------------");
                                        }
                                    }
                                    if (responseType.equals("0F 5A")) {
                                        String pulsatorAlarm[] = responses[responseCount].trim().split(" ");
                                        if (pulsatorAlarm.length == 15) {
                                            alarm = pulsatorDataAnalizer.getAlarm("FF FF " + responses[responseCount].trim());
                                            alarm = "!ALARM#" + "UNITID:" + currentTestUnitID + "#" + alarm;
                                            if (!alarm.contains("报警解除")) {
                                                synchronized (this) {
                                                    GlobalVariable.databackStream.write(alarm.getBytes());
                                                }
                                            }
                                            // 取出alarm中的信息
                                            String[] alarmMess = alarm.split("#");
                                            String alarmMessjiechu = alarmMess[0];
                                            System.out.println("message:" + alarm);
                                        }
                                    }
                                }
                                // 滚筒
                                if (currentModelAndType.equals("2")) {
                                    if (responseType.equals("7D 01")) {
                                        date7DTemp = responses[responseCount].trim();
                                        String roller7DSize[] = date7DTemp.split(" ");
                                        if (roller7DSize.length == 83) {
                                            result7D = rollerDataAnalizer.get7DData("FF FF " + date7DTemp);
                                            result7D = "!DATA#" + "UNITID:" + currentTestUnitID + "#" + result7D;
                                            if (rollerDataAnalizer.ifNeedtoRestart == true) {
                                                if (restartTime != null) {
                                                    if (Duration.between(restartTime, Instant.now()).getSeconds() > 60) {
                                                        RestartMachine();
                                                        rollerDataAnalizer.ifNeedtoRestart = false;
                                                        restartTime = Instant.now();
                                                    } else
                                                        continue;
                                                } else {
                                                    restartTime = Instant.now();
                                                    RestartMachine();
                                                    rollerDataAnalizer.ifNeedtoRestart = false;
                                                }
                                            }
                                        }
                                    }
                                    if (responseType.equals("0F 5A")) {
                                        alarm = rollerDataAnalizer.getAlarm("FF FF " + responses[responseCount]);
                                        alarm = "!ALARM#" + "UNITID:" + currentTestUnitID + "#" + alarm;
                                        try {
                                            GlobalVariable.databackStream.write(alarm.getBytes());
                                            // 只要接受到报警信息就发送命令不让其继续上报
                                            collectionOutStream.flush();
                                            String almMsg = "!Hex#" + "UNITID:" + currentTestUnitID + "#" + "FF FF "
                                                    + responses[responseCount];
                                            synchronized (this) {
                                                GlobalVariable.databackStreamHex.write(almMsg.getBytes());
                                                GlobalVariable.databackStreamHex.flush();
                                            }
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                                // 干衣机
                                if (currentModelAndType.equals("3")) {
                                }
                            } else {
                                System.out.println("---------------接收到命令缺少7D跟alarm的标识位信息-------------------");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    synchronized (this) {
                        if (!result7D.equals("")) {
                            try {
                                System.out.println(
                                        format.format(new Date()) + ">>>>>>>>>>>>>>>>>>>>>>>" + "返回7D信息:" + result7D);
                                String resultHex = "!Hex#" + "UNITID:" + currentTestUnitID + "#" + "FF FF " + date7DTemp;
                                GlobalVariable.databackStreamHex.write(resultHex.getBytes());
                                GlobalVariable.databackStreamHex.flush();
                                GlobalVariable.databackStream.write(result7D.getBytes());
                                GlobalVariable.databackStream.flush();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            } else {
                MainControl.reInit(currentTestUnitID);
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }

            }
        }
    }
}
